<h2>Why is this an issue?</h2>
<p>A unit test assertion should have only one reason to succeed because it helps to ensure that the test is focused and specific. When a test has
multiple reasons to succeed, it becomes difficult to determine the root cause of a failure if the test fails. This can lead to confusion and wasted
time trying to debug the test.</p>
<p>This rule raises an issue when the following Chai.js assertions are found:</p>
<ul>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_throw"><code>.throw</code></a> are used together and at least one
  argument is provided to <code>.throw</code>. Such assertions succeed when the target either does not throw any exception, or when it throws an
  exception different from the one provided. </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_include"><code>.include</code></a> are used together and an
  <code>object</code> is given to <code>.include</code>. Such assertions succeed when one or multiple key/values are missing. </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_property"><code>.property</code></a> are used together and
  <code>.property</code> is given at least two arguments. Such assertions succeed when the target either doesn’t have the requested property, or when
  this property exists but has a different value. </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_ownpropertydescriptor"><code>.ownPropertyDescriptor</code></a> are
  used together and <code>.ownPropertyDescriptor</code> is given at least two arguments. Such assertions succeed when the target either doesn’t have
  the requested property descriptor, or its property descriptor is not deeply equal to the given descriptor </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_members"><code>.members</code></a> are used together. Such
  assertions succeed when one or multiple members are missing. </li>
  <li> When <a href="https://www.chaijs.com/api/bdd/#method_change"><code>.change</code></a> and <a
  href="https://www.chaijs.com/api/bdd/#method_by"><code>.by</code></a> are used together. Such assertions succeed when the target either decreases or
  increases by the given delta </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_increase"><code>.increase</code></a> are used together. Such
  assertions succeed when the target either decreases or stays the same. </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_decrease"><code>.decrease</code></a> are used together. Such
  assertions succeed when the target either increases or stays the same. </li>
  <li> When <code>.not</code> negates <a href="https://www.chaijs.com/api/bdd/#method_by"><code>.by</code></a>. Such assertions succeed when the
  target didn’t change by one specific delta among all the possible deltas. </li>
  <li> When <code>.not</code> and <a href="https://www.chaijs.com/api/bdd/#method_finite"><code>.finite</code></a> are used together. Such assertions
  succeed when the target either is not a <code>number</code>, or is one of <code>Nan</code>, positive <code>Infinity</code>, negative
  <code>Infinity</code>. </li>
</ul>
<pre data-diff-id="1" data-diff-type="noncompliant">
const expect = require('chai').expect;

describe("Each Chai.js assertion", function() {
    const throwsTypeError = () =&gt; { throw new TypeError() }

    it("has more than one reason to succeed", function() {
        expect(throwsTypeError).to.not.throw(ReferenceError) // Noncompliant
        expect({a: 42}).to.not.include({b: 10, c: 20});  // Noncompliant
        expect({a: 21}).to.not.have.property('b', 42); // Noncompliant
        expect({a: 21}).to.not.have.ownPropertyDescriptor('b', {   // Noncompliant
            configurable: true,
            enumerable: true,
            writable: true,
            value: 42,
        });
        expect([21, 42]).to.not.have.members([1, 2]); // Noncompliant

        let myObj = { value: 1 }
        const incThree = () =&gt; { myObj.value += 3; };
        const decThree = () =&gt; { myObj.value -= 3; };
        const doNothing = () =&gt; {};

        expect(incThree).to.change(myObj, 'value').by(3); // Noncompliant
        expect(decThree).to.change(myObj, 'value').by(3); // Noncompliant

        expect(decThree).to.not.increase(myObj, 'value'); // Noncompliant
        expect(incThree).to.not.decrease(myObj, 'value'); // Noncompliant

        expect(doNothing).to.not.increase(myObj, 'value'); // Noncompliant
        expect(doNothing).to.not.decrease(myObj, 'value'); // Noncompliant

        expect(incThree).to.increase(myObj, 'value').but.not.by(1); // Noncompliant

        let toCheck;
        expect(toCheck).to.not.be.finite; // Noncompliant
    });
});
</pre>
<p>By having only one reason to succeed, the test is more precise and easier to understand. It also helps to ensure that the test is testing only one
specific behavior or functionality of the code, which makes it easier to identify and fix any issues that arise.</p>
<pre data-diff-id="1" data-diff-type="compliant">
const expect = require('chai').expect;

describe("Each Chai.js assertion", function() {
    const throwsTypeError = () =&gt; { throw new TypeError() }

    it("has only one reason to succeed", function() {
        expect(throwsTypeError).to.throw(TypeError)
        expect({a: 42}).to.not.have.any.keys('b', 'c');
        expect({a: 21}).to.not.have.property('b');
        expect({a: 21}).to.not.have.ownPropertyDescriptor('b');
        expect([21, 42]).to.not.include(1).and.not.include(2);

        let myObj = { value: 1 }
        const incThree = () =&gt; { myObj.value += 3; };
        const decThree = () =&gt; { myObj.value -= 3; };
        const doNothing = () =&gt; {};

        expect(incThree).to.increase(myObj, 'value').by(3);
        expect(decThree).to.decrease(myObj, 'value').by(3);

        expect(decThree).to.decrease(myObj, 'value').by(3);
        expect(incThree).to.increase(myObj, 'value').by(3);

        expect(doNothing).to.not.change(myObj, 'value');

        expect(incThree).to.increase(myObj, 'value').by(3);

        let toCheck;
        // Either of the following is valid
        expect(toCheck).to.be.a('string');
        expect(toCheck).to.be.NaN;
        expect(toCheck).to.equal(Infinity);
        expect(toCheck).to.equal(-Infinity);
    });
});
</pre>
<p>Having only one reason to succeed also helps to make the test more maintainable. If the test needs to be updated or modified in the future, it is
easier to do so when the test is focused on a single behavior or functionality.</p>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_by"><code>.by</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_change"><code>.change</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_decrease"><code>.decrease</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_finite"><code>.finite</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_include"><code>.include</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_increase"><code>.increase</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_members"><code>.members</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_ownpropertydescriptor"><code>.ownPropertyDescriptor</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_property"><code>.property</code></a> </li>
  <li> Chai.js Documentation - <a href="https://www.chaijs.com/api/bdd/#method_throw"><code>.throw</code></a> </li>
</ul>
